#!/usr/bin/perl

#folders
$root_folder="/home/dongjin2/SVNROOT/ethernet-switch";
$result_folder="$root_folder/rinse_test/2_to_1/exp6"; #root dir to store experimental resutls
$aggregated_result="$result_folder/real_data_result.txt"; #results for all experiments, used for plot

$runs=1; # number of repeated experiment (same setting)

#used to calculate gap (not used now)
$packet_size=1500; #byte

@speed;
#specify sending rate
$start_sending_rate=100;#Mb/s
$end_sending_rate=1000;
$sending_rate_gap=100;

$num_pkts = 10000;
#100Mb/s - 1000Mb/s, every 100Mb/s, slightly less than specified rate, according to real experiment
@flow1_send_rate=(-1,-1,-1,-1,-1,-1,-1,-1, 887.1e6,-1);
@flow2_send_rate=(99.081e6, 198.162e6, 295.875e6, 396.32e6, 495.404e6, 594.63e6, 691.28e6, 791.602e6, 887.624e6, 978e6);

#print "@flow1_send_rate\n";
#print "@flow2_send_rate\n";

for($i=0; $i<=$#flow1_send_rate; $i++)
{
	$flow1_send_interval[$i]=$packet_size*8.0/$flow1_send_rate[$i];
	$flow2_send_interval[$i]=$packet_size*8.0/$flow2_send_rate[$i];
}

#print "@flow1_send_interval\n";
#print "@flow2_send_interval\n";

#calculate speed
for($b=$start_sending_rate, $a=0; $b<=$end_sending_rate; $b+=$sending_rate_gap, $a++)
{
	$speed[$a]=$b;
	#print "\n speed = $speed[$a]\n";
}

open(OUT_RESULT, ">$aggregated_result") or die "$aggregated_result cannot be opened.\n";
print OUT_RESULT "flow1(Mb/s), flow2(Mb/s), mode, loss_rate, lp_mean, lp_std, delay_mean(us), delay_std(us), jitter(us)\n";

#post-process data
#for($j=0; $j<=$#speed; $j++)
for($j=8; $j<=8; $j++)
{
	#for($k=0; $k<=$#speed; $k++)
	for($k=4; $k<=$#speed; $k++)
	{
		chdir "$result_folder/$speed[$j]M/$speed[$k]M/real";
		print "Processing $result_folder/$speed[$j]M/$speed[$k]M/real\n";		

		#$in_flow="flow_table_sorted.csv";
		$in_flow="1_flow_table.csv";
		#$in_flow="2_flow_table.csv";
		$out_delay="delay.txt";
		$out_loss_episode="loss_episode.txt";

		#sort according arrival_timestamp
		#system("sort flow_table.csv > $in_flow");

		#open files
		open(IN_FLOW, $in_flow) or die "$in_flow cannot be opened.\n";
		open(OUT_DELAY, ">$out_delay") or die "$out_delay cannot be opened.\n";
		open(OUT_LP, ">$out_loss_episode") or die "$out_loss_episode cannot be opened.\n";

		#compute end time
		$line=<IN_FLOW>;
		chomp($line);
		@line_block=split(', ', $line);
		$delay=$line_block[4];
		$arrival_time_start=$line_block[0];
		print OUT_DELAY "$delay\n";
		print "beginning: delay=$delay, arrival_time=$arrival_time_start\n";

		if($flow1_send_interval[$j]<=$flow2_send_interval[$k])
		{
			$end_time = $num_pkts*$flow1_send_interval[$j]+$arrival_time_start;
		}
		else
		{
			$end_time = $num_pkts*$flow2_send_interval[$k]+$arrival_time_start;			
		}
		print "end time = $end_time\n";

		#separate delay and loss_episode into two files			
		$prev_delay=$delay;
		$loss_counter=0;
		$successive_loss_counter=0;
		$total_counter=1;

		while($line=<IN_FLOW>)
		{				
			chomp($line);
			@line_block=split(', ', $line);
			$delay=$line_block[4];
			$arrival_time=$line_block[0];
	
			#print("$arrival_time, $delay\n");

			if($arrival_time>$end_time)
			{
				last;
			}
				
			if($delay!=0)
			{
				print OUT_DELAY "$delay\n";
			}
			
			if($delay==0)
			{
				$loss_counter=$loss_counter+1;
				$successive_loss_counter=$successive_loss_counter+1;						
			}				

			if($delay!=0 and $prev_delay==0)
			{
				print OUT_LP "$successive_loss_counter\n";
				$successive_loss_counter=0;
			}

			$prev_delay=$delay;
			$total_counter=$total_counter+1;
		}

		close(OUT_LP);
		close(OUT_DELAY);
		close(IN_FLOW);

		#compute delay mean/std/jitter
		$in_delay="delay.txt";
		open(INPUT_DELAY, $in_delay) or die "$in_delay cannot be opened.\n";
	
		$delay_counter = 0;
		$delay_sum = 0;
		$delay_square_sum = 0;
		$delay_mean = 0;
		$delay_var = 0;
		$delay_std = 0;
		$jitter_total = 0;
		$jitter = 0;

		$my_delay = <INPUT_DELAY>;
		chomp($my_delay);
		$delay_counter++;
		$delay_sum += $my_delay;
		$delay_square_sum += $my_delay**2;
		$prev_my_delay = $my_delay;

		while($my_delay = <INPUT_DELAY>)
		{			
			chomp($my_delay);			
			$delay_counter++;
			$delay_sum += $my_delay;
			$delay_square_sum += $my_delay**2;
			$jitter_total += abs($my_delay-$prev_my_delay);
		        $prev_my_delay = $my_delay;
		}

		$delay_mean = $delay_sum /$delay_counter;
		$delay_autocor = $delay_square_sum/$delay_counter;
		$delay_var = $delay_autocor-$delay_mean**2;
		$delay_std = sqrt($delay_var);
		$jitter = $jitter_total/($delay_counter-1);

		$formatted_delay_mean=sprintf("%.3f", $delay_mean);
		$formatted_delay_std=sprintf("%.3f", $delay_std);
		$formatted_jitter=sprintf("%.3f", $jitter);
		close(INPUT_DELAY);
					
		#compute loss_episode mean and std
		$in_loss_episode="loss_episode.txt";
		open(INPUT_LP, $in_loss_episode) or die "$in_loss_episode cannot be opened.\n";

		$lp_counter = 0;
		$lp_sum = 0;
		$lp_square_sum = 0;
		$lp_mean = 0;
		$lp_var = 0;
		$lp_std = 0;

		while($my_lp = <INPUT_LP>)
		{			
			chomp($my_lp);			
			$lp_counter++;
			$lp_sum += $my_lp;
			$lp_square_sum += $my_lp**2;
		}

		$lp_mean = $lp_sum /$lp_counter;
		$lp_autocor = $lp_square_sum/$lp_counter;
		$lp_var = $lp_autocor-$lp_mean**2;
		$lp_std = sqrt($lp_var);

		$formatted_lp_mean=sprintf("%.3f", $lp_mean);
		$formatted_lp_std=sprintf("%.3f", $lp_std);
		close(INPUT_IP);
			
		#output result
		#flow1_sending_rate, flow2_sending_rate, switch_mode, avg_loss_rate, loss_episode_mean, loss_episode_std, delay_mean, delay_std, jitter
		#print "loss = $loss_counter, total = $total_counter\n";
		$loss_rate=$loss_counter*1.0/$total_counter;
		$formatted_loss_rate=sprintf("%.3f", $loss_rate);
		print OUT_RESULT "$speed[$j] $speed[$k] real $formatted_loss_rate $formatted_lp_mean $formatted_lp_std $formatted_delay_mean $formatted_delay_std $formatted_jitter\n";
	}
}

close(OUT_RESULT);

chdir "$root_folder/script/rinse_test";
